package crontab

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/spf13/cast"
	"longmen/server/config/global"
	cache2 "longmen/server/internal/rpc/tencentim/cache"
	"longmen/server/internal/rpc/tencentim/imsdk"
	messages2 "longmen/server/internal/rpc/tencentim/messages"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/db/mysql/models/models_live"
	"longmen/server/pkg/db/mysql/models/models_main"
	"longmen/server/pkg/db/redis/cache"
	"math/rand"
	"sync"
	"time"
)

var ReplayChatClientHub *ReplayChatHub

type ReplayChatHub struct {
	LoginChan    chan *client
	LoginOutChan chan *client
	mu           sync.Locker
}

func NewReplayChatHub() *ReplayChatHub {
	return &ReplayChatHub{
		LoginChan:    make(chan *client, 1000),
		LoginOutChan: make(chan *client, 1000),
	}
}

func (h *ReplayChatHub) Run(ctx context.Context) {
	for {
		select {
		case c := <-h.LoginChan:
			c.Send(ctx)
		case c := <-h.LoginOutChan:
			c.SetLoginOut()
		case <-ctx.Done():
			// 当上下文完成时优雅地退出循环
			return
		}
	}
}

func (h *ReplayChatHub) EnterReplayRoom(roomId int, userId int) bool {
	user, err := cache2.GetUser(userId)
	if err != nil {
		return false
	}
	roomInfo, b := cache.LiveData(roomId)
	if b == 0 || roomInfo.ReplyVideo != 1 { //未开播或不是回放不处理
		return false
	}
	var liveHistory = models_live.LiveHistory{}
	err = global.Live().Model(&models_live.LiveHistory{}).Where("event_title = ? and  matchid = ?", roomInfo.Title, roomInfo.Matchid).First(&liveHistory).Error
	if err != nil {
		return false
	}

	clientInfo := &client{
		LiveEndTime:   liveHistory.EndStamp,
		LiveStartTime: liveHistory.StartStamp,
		RoomId:        roomId,
		User:          user,
	}
	h.LoginChan <- clientInfo
	return true
}

func (h *ReplayChatHub) LeaveRoom() {

}

type client struct {
	RoomId        int
	LiveStartTime int64
	LiveEndTime   int64
	User          *models_main.User
	loginOut      bool
	mu            sync.Mutex // 添加锁以确保 loginOut 的线程安全
}

func (c *client) Send(ctx context.Context) {
	limit := 50
	page := 1
	go func() {
		for {
			select {
			case <-ctx.Done():
				return
			default:
				if c.isLoginOut() {
					return
				}
				chatData, total := c.getReplayChatHis(page)
				if len(chatData) == 0 {
					return
				}
				c.processMessages(ctx, chatData)
				if total < limit {
					return
				}
				page++

				// 适当的延时，避免过度频繁的轮询
				time.Sleep(100 * time.Millisecond)
			}
		}
	}()
}

func (c *client) processMessages(ctx context.Context, chatData []*models_main.ChatHistory) {
	for _, v := range chatData {
		if c.isLoginOut() {
			return
		}
		resp := &messages2.RoomUserSayMessageToNats{
			SentMessageStruct: messages2.SentMessageStruct{Type: messages2.RoomUserSayMessageType},
			Id:                cache.GetChatAutoId(),
			Content:           v.Content,
			UserId:            c.User.Id,
			ClientName:        c.User.NickName,
			Level:             rand.Intn(4) + 1,
			Props:             nil,
			RoomId:            c.RoomId,
			Role:              0,
			CreateTime:        time.Now().Unix(),
		}
		jsonString, err := json.Marshal(resp)
		if err != nil {
			continue
		}

		err = imsdk.GetSdk().SendUser(cast.ToString(c.User.Id), string(jsonString))
		fmt.Printf("推送消息:err:%v,content:%s", err, v.Content)
	}
}

func (c *client) getReplayChatHis(page int) ([]*models_main.ChatHistory, int) {
	rs, _ := db_main.GetEsChatHistoryByTimeRange(c.RoomId, c.LiveStartTime, c.LiveEndTime, page)
	return rs, len(rs)
}

// 用于检查 loginOut 状态的线程安全方法
func (c *client) isLoginOut() bool {
	c.mu.Lock()
	defer c.mu.Unlock()
	return c.loginOut
}

func (c *client) SetLoginOut() {
	c.mu.Lock()
	defer c.mu.Unlock()
	c.loginOut = true
}
